package core;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;

import file.Unione;
	 
public class ReceiverManager implements Runnable {
	private String saveDir;
	private Socket socket;
	private String nomeFile;
	private long lunghezzaFile;
	private DataInputStream dis;
	private DataOutputStream dos;
	private String originalNomeFile;
	private String nomeUltimoFile = "";
	private int numeroSocket = -1;
	private String nomeFileDaSalvare;
	
	@SuppressWarnings("deprecation")
	public ReceiverManager(Socket socket, String sDir, int numero) {
		this.socket = socket;
		this.saveDir = sDir;
		this.numeroSocket = numero;

		System.out.println("********************** RECEIVE MANAGER **********************");
	    try {
	    	dis = new DataInputStream(socket.getInputStream());
	    	
	    	nomeFile = dis.readLine();
	      	System.out.println("Il nome del file che si sta ricevendo e': " + nomeFile);
	      	
	      	lunghezzaFile = Long.valueOf(dis.readLine());
	      	System.out.println("La lunghezza del file che si sta ricevendo e': " + lunghezzaFile);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		originalNomeFile = nomeFile;

		String nomeFileNEW = "";
		int numeroNomeFile = nomeFile.indexOf(".0");
		if (numeroNomeFile != -1) {
			nomeFileNEW = nomeFile.substring(0, numeroNomeFile);
		} else {
			nomeFileNEW = nomeFile;
		}
		
		nomeFileDaSalvare = new File ((saveDir.concat("//")).concat(nomeFileNEW)).getAbsolutePath();;
		String absolute = new File ((saveDir.concat("//")).concat(nomeFile)).getAbsolutePath();

		try {
			dos = new DataOutputStream(new FileOutputStream(absolute));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public void run() {
		try {
			System.out.println("Presa in carico della nuova connessione da: " + socket);
	        byte[] dimFile = new byte[1024];
	        byte[] fineFile = null;
	        if (!nomeFile.equals(nomeUltimoFile)) {
		        System.out.println("Il file che si sta ricevendo e': " + nomeFile);
		        nomeUltimoFile = nomeFile;
	        }
	        
            int numPack = (int) lunghezzaFile/1024;
        	int temp = 1024*numPack;
        	int resto=(int)lunghezzaFile-temp;
        	
        	System.out.println("Il resto e' '" + resto + "'");
        	int count=0;
        	while(count < numPack){
        		dis.read(dimFile);
        		dos.write(dimFile);
        		if (!nomeFile.equals(nomeUltimoFile)) {
    		        System.out.println("Il file che si sta ricevendo e': " + nomeFile);
    		        nomeUltimoFile = nomeFile;
    	        }
        		count++;
        	}
        	
        	if (resto != 0  && resto > 0){
        		fineFile=new byte[resto];
        		dis.read(fineFile);
        		dos.write(fineFile);
        		System.out.println(nomeFile+" Ricezione resto");
        	}

        	String fileParte = " (1)";
    		int punto = originalNomeFile.indexOf(".");
    		String inizioNomeFile = originalNomeFile.substring(0, punto);
    		String fineNomeFile = originalNomeFile.substring(punto++);
    		String newNomeFile = (inizioNomeFile.concat(fileParte)).concat(fineNomeFile);
    		String absolute = new File((saveDir.concat("//")).concat(newNomeFile)).getAbsolutePath();
    		
        	while (!socket.isClosed() && !(dis.read()==-1)) {
        		nomeUltimoFile = "";
        		dos = new DataOutputStream(new FileOutputStream(absolute));
        		dimFile = new byte[1024];
    	        fineFile = null;
                numPack = (int) lunghezzaFile/1024;
            	temp = 1024*numPack;
            	resto=(int)lunghezzaFile-temp;
            	count=0;
            	
            	// System.out.println("DIM " + newNomeFile + " = "+dis.read());
            	
        		while(count < numPack){
            		dis.read(dimFile);
            		dos.write(dimFile);
            		if (!newNomeFile.equals(nomeUltimoFile)) {
        		        System.out.println("Il file che si sta ricevendo e': " + newNomeFile);
        		        nomeUltimoFile = newNomeFile;
        	        }
            		count++;
            	}
            	
            	if (resto != 0  && resto > 0){
            		fineFile=new byte[resto];
            		dis.read(fineFile);
            		dos.write(fineFile);
            		System.out.println(newNomeFile+" Ricezione resto");
            	}
        	}

        	dis.close();
        	dos.close();
            socket.close();
            
        	System.out.println("+++++++++++++++ Rimozione del file temporaneo +++++++++++++++");
        	rimozioneFile(newNomeFile, saveDir);
        	System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++");

        	/*
        	 * Alla chiusura della prima socket effettua l'unione dei frammenti
        	 * ottenuti e la rimozione dei file temporanei
        	 */
        	if (numeroSocket==1) {
            	System.out.println("+++++++++++++ Unione dei frammenti ottenuti +++++++++++++");
        		Unione unione = new Unione();
        		unione.effettua(nomeFileDaSalvare);
        		rimozioneFilesFrammenti(nomeFileDaSalvare, saveDir);
            	System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        	}
        	
        } catch (Exception e) {
        	e.printStackTrace();
	    }
	}

	public void rimozioneFile (String nomeFileCancellare, String percorsoBase) {
		nomeFileCancellare = nomeFileCancellare.replace("\\", "//");
		int slash = nomeFileCancellare.indexOf("//");
		while (slash != -1) {
			nomeFileCancellare = nomeFileCancellare.substring(slash+2);
			slash = nomeFileCancellare.indexOf("//");
		}
		
		File directory = new File(percorsoBase);
		File[] files = directory.listFiles();
		for (File f : files) {
			String nomeF = f.getName();
			if (nomeF.equals(nomeFileCancellare)) {
				System.out.println("Elimina " + nomeF);
				f.delete();
			}
		}
	}

	public void rimozioneFilesFrammenti (String nomeFileDaSalvare, String percorsoBase) {
		nomeFileDaSalvare = nomeFileDaSalvare.replace("\\", "//");
		int slash = nomeFileDaSalvare.indexOf("//");
		while (slash != -1) {
			nomeFileDaSalvare = nomeFileDaSalvare.substring(slash+2);
			slash = nomeFileDaSalvare.indexOf("//");
		}
		
		File directory = new File(percorsoBase);
		File[] files = directory.listFiles();
		for (File f : files) {
			String nomeF = f.getName();
			if (nomeF.contains(nomeFileDaSalvare+".")) {
				System.out.println("Elimina " + nomeF);
				f.delete();
			}
		}
	}
}
